//   定制请求的实例
import { ElMessage, ElMessageBox, ElLoading } from "element-plus";
import axios from "axios";
//loading
import { showLoading, hideLoading } from "../utils/loading";
import { useUserInfoStore } from "@/store/userInfoStore";
import { tansParams } from "@/utils/common";
import { saveAs } from "file-saver";
import { blobValidate } from "@/utils/file.js";

// 定义一个变量，记录公共的前缀，baseURL
// const baseURL = 'http://localhost:8080';
const baseURL = "/api";
axios.defaults.headers["Content-Type"] = "application/json;charset=utf-8";
const instance = axios.create({
  baseURL: baseURL,
  timeout: 5000, // 请求超时时间 5s
});
// 引入一个全局变量来存储标志位
let isShowingLogoutDialog = false;
// 添加请求拦截器
instance.interceptors.request.use(
  (config) => {
    const userInfoToken = useUserInfoStore();
    let tokenName = userInfoToken.tokenName;
    if (userInfoToken.tokenName == null) {
      tokenName = "satoken";
    }

    let tokenValue = userInfoToken.tokenInfo;
    // 添加token
    // 判断有没有token
    if (tokenValue) {
      config.headers[tokenName] = tokenValue;
    }
    // 遮罩
    showLoading();
    // get请求映射params参数
    if (config.method === "get" && config.params) {
      let url = config.url + "?" + tansParams(config.params);
      url = url.slice(0, -1);
      config.params = {};
      config.url = url;
    }

    return config;
  },
  (err) => {
    //对请求错误的回调
    ElMessage.error("请求发送失败");
    return Promise.reject(err);
  }
);
// 惰性加载
import router from "@/router";

// 添加响应拦截器
instance.interceptors.response.use(
  (res) => {
    console.log("common-res:", res);

    // 响应拦截进来隐藏loading效果，此处采⽤延时处理是合并loading请求效果，避免多次请求loading关闭⼜开启
    setTimeout(() => {
      hideLoading();
    }, 200);

    // 二进制数据则直接返回
    if (
      res.request.responseType === "blob" ||
      res.request.responseType === "arraybuffer"
    ) {
      console.log("blob --");
      return res.data;
    }
    // 操作失败   则弹出  失败信息
    if (res.data.code == 500) {
      ElMessage.error(res.data.msg ? res.data.msg : "服务异常");
    }

    // 查询登录状态，或者token是否过期。请求正常时---
    if (res.data.code === 401) {
      if (!isShowingLogoutDialog) {
        isShowingLogoutDialog = true; // 设置标志位1
        ElMessageBox.confirm(
          "登录状态已过期，您可以继续留在该页面，或者重新登录",
          "系统提示",
          {
            confirmButtonText: "重新登录",
            cancelButtonText: "取消",
            type: "warning",
          }
        )
          .then(() => {
            // 返回登录页  登陆后返回之前的页面
            let redirectUrl = router.currentRoute.value.fullPath;

            router.push("/login?redirectUrl=" + redirectUrl);
          })
          .finally(() => {
            isShowingLogoutDialog = false; // 清除标志位
          });
      }
      return Promise.reject("无效的会话，或者会话已过期，请重新登录。");
    }
    // if (res.data.code == 0 && res.data.msg == "未登录") {
    //   ElMessage.error("请先登录！");
    //   // 返回拒绝的promise对象
    //   return Promise.reject(res.data);
    //   // 返回登录页
    //   router.push("/");
    // }
    return res.data;
  },
  (error) => {
    // 响应拦截进来隐藏loading效果，此处采⽤延时处理是合并loading请求效果，避免多次请求loading关闭⼜开启
    setTimeout(() => {
      hideLoading();
    }, 200);

    // 查看错误信息，判断弹出消息。
    console.log("error:" + error);
    let { message } = error;
    if (message == "Network Error") {
      message = "后端接口连接异常";
    } else if (message.includes("timeout")) {
      message = "系统接口请求超时";
    } else if (message.includes("Request failed with status code")) {
      message = "系统接口" + message.substr(message.length - 3) + "异常";
    }

    ElMessage({ message: message, type: "error", duration: 5 * 1000 });

    // 查询登录状态，或者token是否过期。请求异常时---
    if (error.status == 401) {
      if (!isShowingLogoutDialog) {
        isShowingLogoutDialog = true; // 设置标志位1
        ElMessageBox.confirm("登录状态已过期,请重新登录", "系统提示", {
          confirmButtonText: "重新登录",
          cancelButtonText: "取消",
          type: "warning",
        })
          .then(() => {
            let redirectUrl = router.currentRoute.value.fullPath;
            // 返回登录页  登陆后返回之前的页面
            router.push(
              // "/"
              // console.log('router.fullPath:',router.currentRoute.value.fullPath),
              "/login?redirectUrl=" + redirectUrl
            );
          })
          .finally(() => {
            isShowingLogoutDialog = false; // 清除标志位
          });
      }
      return Promise.reject(error); // 异常的状态转化成失败的状态
    }
  }
);

// 通用下载方法
export function download(url, params, filename, config) {
  // 遮罩
  showLoading();
  return instance({
    url: url,
    method: "post",
    data: params,
    responseType: "blob",
    ...config,
  })
    .then(async (data) => {
      const isBlob = blobValidate(data);
      if (isBlob) {
        const blob = new Blob([data]);
        saveAs(blob, filename);
      } else {
        const resText = await data.text();
        const rspObj = JSON.parse(resText);
        const errMsg =
          errorCode[rspObj.code] || rspObj.msg || errorCode["default"];
        ElMessage.error(errMsg);
      }
      hideLoading();
    })
    .catch((r) => {
      console.error(r);
      ElMessage.error("下载文件出现错误!");
      hideLoading();
    });
}

// 防抖函数   避免高频、耗时的操作、以最后一次调用为主的函数使用，可以减少资源消耗
function debounce(fn, delay = 1000) {
  let timer = null;
  return function (...args) {
    clearTimeout(timer);
    // 延迟执行
    timer = setTimeout(() => {
      // 传入参数（数组） 直接运行  （可以改变this指向）this指向调用者(debounce的调用者)
      fn.apply(this, args);
    }, delay);
  };
}

// 节流函数 会完成前一次触发的函数，才会执行下一次的函数
function throttle(fn, delay = 1000) {
  let timer = true;
  return function (...args) {
    if (!timer) {
      timer = setTimeout(() => {
        fn.apply(this, args);
        timer = null;
      }, delay);
    }
  };
}

export default instance;
